﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities;
using Sustainalytics.Portfolios.BL.Exceptions;
using Sustainalytics.Utils;

namespace Sustainalytics.Portfolios.BL
{



    //public class PortfolioDetailsManagement : IPortfolioDetailsManagement


            //{
    //    private readonly IRepositoryCollection<PortfolioDetails> _portfolioDetailsRepository;
    //    private readonly IRepositoryCollection<Portfolio> _portfolioRepository;

    //    public PortfolioDetailsManagement(IRepositoryCollection<PortfolioDetails> portfolioDetailsRepository, IRepositoryCollection<Portfolio> portfolioRepository )
    //    {
    //        _portfolioDetailsRepository = portfolioDetailsRepository;
    //        _portfolioRepository = portfolioRepository;
    //    }

    //    public void AddPortfolioSecurities(ICollection<PortfolioDetails> portfolioDetails)
    //    {
    //        if (portfolioDetails.IsNullOrEmpty())
    //        {
    //            throw new ArgumentNullException("portfolioDetails");
    //        }
    //        foreach (var portfolioDetail in portfolioDetails)
    //        {
    //            portfolioDetail.Id = Guid.NewGuid();
    //        }
    //        _portfolioDetailsRepository.CreateOrUpdateBatch(portfolioDetails);
    //    }

    //    private bool SecurityExists(Guid portfolioId, int securityId)
    //    {
    //        var count= _portfolioDetailsRepository.ReadCount(p => p.PortfolioId == portfolioId && p.SecurityId == securityId);
    //        return (count >0);
    //    }

    //    public void InsertPortfolioDetails(Guid portfolioId, int securityId, PortfolioUserClaims userClaims)
    //    {
    //        var securityExists =SecurityExists(portfolioId, securityId);
    //        if (securityExists)
    //        {
    //            throw new PortfolioDetailsExistsInPortfolio();
    //        }
    //        var portfolio = _portfolioRepository.Read(portfolioId);

    //        if (UserIsAuthorized(userClaims, portfolio, TODO))
    //        {
    //            throw new PortfolioDetailsInsertUnauthorisedException();
    //        }
          
    //            //if(Sustainalytics.Utils.UnitTestDetector.IsInUnitTest)
    //            //{
    //            //    PortfolioDetails portfolioDetails = new PortfolioDetails();
    //            //    portfolioDetails.Id = new Guid();
    //            //    portfolioDetails.CompanyId = id;
    //            //    portfolioDetails.CompanyName = "Test post";
    //            //    portfolioDetails.CompanyNameLowercase = "test post";
    //            //    portfolioDetails.CompanyNameUrlFriendly = "Test post";
    //            //    portfolioDetails.PortfolioId = portfolioId;
    //            //    portfolioDetails.UniverseIds = null;
    //            //    _portfolioCompanyRepo.AddPortfolioCompany(portfolioCompany);
    //            //}
    //            //else
    //            //{
    //            //ReferenceData company = _clientDWRepo.GetReferenceDataByCompanyId(id);
    //            //CorporateData companyCD = _clientDWRepo.GetCorporateDataByCompanyId(id);
    //            //PortfolioDetails portfolioDetails = new PortfolioDetails();
    //            //portfolioDetails.Id = new Guid();
    //            //portfolioDetails.CompanyId = id;
    //            //portfolioDetails.MatchedInfo.CompanyName = companyCD.CompanyName;
    //            //portfolioDetails.MatchedInfo.CapitalIQId =  Int32.Parse(companyCD.CapitalIQID);
    //            //portfolioDetails.CompanyNameLowercase = companyCD.CompanyNameLowercase;
    //            //portfolioDetails.CompanyNameUrlFriendly = companyCD.CompanyNameUrlFriendly;
    //            //portfolioDetails.PortfolioId = portfolioId;
    //            //portfolioDetails.UniverseIds = companyCD.UniverseIds;


    //            //string argsStr = LogArgument.GetString(
    //            //    new
    //            //    {
    //            //        PortfolioId = portfolioDetails.PortfolioId,
    //            //        CompanyId = portfolioDetails.CompanyId
    //            //    });

    //            //PortfolioDetailsManagementEventSource.Log.AddPortfolioDetails(argsStr);
    //            //_portfolioDetailsRepo.AddPortfolioDetails(portfolioDetails);
    //            //PortfolioDetailsManagementEventSource.Log.AddPortfolioDetailsSuccess(argsStr);

    //            //portfolio.CompanyCount++;
    //            //portfolio.DateModified = DateTime.Now;
    //            //_portfolioRepo.UpdatePortfolio(portfolio);
    //            //}
            
    //    }

    //    private static bool UserIsAuthorized(PortfolioUserClaims userClaims, PortfolioBase portfolio, PortfolioActivity activity)
    //    {
    //        if (activity==PortfolioActivity.Write)
    //            return portfolio.AccountId == userClaims.AccountId ||
    //               portfolio.AddedByUserId.Equals(userClaims.UserId);
    //        if (activity == PortfolioActivity.Read)
    //            return (portfolio.AddedByUserId == userClaims.UserId ||
    //                    (portfolio.SharingStatus == PortfolioSharingStatus.Shared &&
    //                     portfolio.AccountId == userClaims.AccountId));
    //        return false;

    //    }

    //    public IList<PortfolioDetails> GetSecuritiesForPortfolio(Guid portfolioId)
    //    {
    //        return _portfolioDetailsRepository.ReadWhere(x=>x.PortfolioId==portfolioId);
    //    }

    //    public long GetPortfolioSecuritiesCount(PortfolioDetailsFilter filter, PortfolioUserClaims userClaims)
    //    {
    //        string argsStr = LogArgument.GetString(filter.PortfolioId);
    //        try
    //        {
    //            var portfolio = _portfolioRepository.Read(filter.PortfolioId);
    //            if (portfolio == null || !UserIsAuthorized(userClaims, portfolio, PortfolioActivity.Read))
    //            {
    //                return 0;
    //            }
    //            PortfolioDetailsManagementEventSource.Log.GetPortfolioDetailsCount(argsStr);
    //            var count = _portfolioDetailsRepository.ReadCount(p => p.PortfolioId == filter.PortfolioId);
    //            PortfolioDetailsManagementEventSource.Log.GetPortfolioDetailsCountSuccess(argsStr);
    //            return count;
    //        }
    //        catch (Exception ex)
    //        {
    //            PortfolioDetailsManagementEventSource.Log.GetPortfolioDetailsCountError(argsStr, ex);
    //            throw;
    //        }
    //    }

    //    public IList<PortfolioDetails> GetPortfolioDetails(PortfolioDetailsFilter filter, PortfolioUserClaims userClaims, int? skip = null, int? take = 100, string[] orderBy = null, bool orderByAsc = true)
    //    {
    //        string argsStr = LogArgument.GetString(filter.PortfolioId);
    //        try
    //        {
    //            Portfolio portfolio = _portfolioRepository.Read(filter.PortfolioId);
    //            if (portfolio != null && UserIsAuthorized(userClaims,portfolio,PortfolioActivity.Read))
    //            {
    //                PortfolioDetailsManagementEventSource.Log.GetPortfolioDetails(argsStr);

    //                Ordering<PortfolioDetails> orderingDetails = null;
    //                if (!orderBy.IsNullOrEmpty())
    //                    orderingDetails = orderByAsc
    //                        ? Ordering<PortfolioDetails>.Ascending(GetExpression(orderBy.FirstOrDefault()))
    //                        : Ordering<PortfolioDetails>.Descending(GetExpression(orderBy.FirstOrDefault()));

                       
    //                var listPortfolioCompany = _portfolioDetailsRepository.ReadWhere(p => p.PortfolioId == filter.PortfolioId, skip, take,orderingDetails);
    //                PortfolioDetailsManagementEventSource.Log.GetPortfolioDetailsSuccess(argsStr);
    //                return listPortfolioCompany;
    //            }
    //            return null;
    //        }
    //        catch (Exception ex)
    //        {
    //            PortfolioDetailsManagementEventSource.Log.GetPortfolioDetailsError(argsStr, ex);
    //            throw;
    //        }
    //    }

    //    public void DeletePortfolioSecuritiesByPortfolioId(Guid portfolioId)
                        //    {
    //        string argsStr = LogArgument.GetString(portfolioId);
    //        try
    //        {
    //            PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetails(argsStr);
    //            _portfolioDetailsRepository.DeleteWhere(p=>p.PortfolioId==portfolioId);
    //            PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetailsSuccess(argsStr);
    //        }
    //        catch (Exception ex)
    //        {
    //            PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetailsError(argsStr, ex);
    //            throw;
    //        }
    //    }

    //    public void DeletePortfolioSecurity(Guid portfolioId, Guid id, PortfolioUserClaims userClaims)
    //    {
    //        Portfolio portfolio = _portfolioRepository.Read(portfolioId);
    //        if (!UserIsAuthorized(userClaims, portfolio, PortfolioActivity.Write))
    //        {
    //            throw new PortfolioDetailsDeleteUnauthorisedException();
    //        }

    //            try
    //            {
    //                PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetails(id.ToString());
    //                _portfolioDetailsRepository.DeleteWhere(x=>x.Id==id);
    //                PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetailsSuccess(id.ToString());
    //                portfolio.CompanyCount--;
    //                portfolio.DateModified = DateTime.Now;
    //                _portfolioRepository.UpdatePortfolio(portfolio);
    //            }
    //            catch (Exception ex)
    //            {
    //                PortfolioDetailsManagementEventSource.Log.DeletePortfolioDetailsError(id.ToString(), ex);
    //                throw;
    //            }
            
    //    }

    //    private static Expression<Func<PortfolioDetails, object>> GetExpression(string orderBy)
    //    {
    //        var parameter = Expression.Parameter(typeof (PortfolioDetails), "p");

    //        Expression expr = parameter;

    //        // use reflection (not ComponentModel) to mirror LINQ 
    //        PropertyInfo pi = typeof (PortfolioDetails).GetProperty(orderBy);
    //        expr = Expression.Property(expr, pi);

    //        return Expression.Lambda<Func<PortfolioDetails, object>>(expr, parameter);
    //    }

    //}
}
